﻿using System;
using System.Net;

namespace EmbeddedSensorCloud.Core.Server
{
    public class ServerException : Exception
    {
        public ServerException() : this("Server exception occured") { }
        public ServerException(string message) : this(message, null) { }
        public ServerException(string message, Exception inner) : base(message, inner) { }

        public override string ToString()
        {
            if (base.InnerException == null)
            {
                return base.Message;
            }

            return string.Format("{0}:{1}   * {2} *", base.Message, Environment.NewLine, base.InnerException.Message);
        }
    }

    public class PortAlreadyInUseException : ServerException
    {
        public readonly int Port;

        public PortAlreadyInUseException(int port) : this(port, "Port already in use") { }
        public PortAlreadyInUseException(int port, string message)
            : base(message)
        {
            this.Port = port;
        }
    }

    public class InvalidIPException : ServerException
    {
        public readonly string IP;

        public InvalidIPException(string ip) : this(ip, "Invalid ip address") { }
        public InvalidIPException(string ip, string message)
            : base(message)
        {
            this.IP = ip;
        }
    }

    public class ServerNotListeningException : ServerException
    {
        public ServerNotListeningException() : base("Server not listening") { }
        public ServerNotListeningException(string message) : base(message) { }
    }

    public class ServerAlreadyListeningException : ServerException
    {
        public readonly IPAddress IP;
        public readonly int Port;

        public ServerAlreadyListeningException(IPAddress ip, int port) 
            : base(string.Format("Server already listening on endpoint {0}:{1}", ip, port)) { }
        
        public ServerAlreadyListeningException(IPAddress ip, int port, string message) : base(message)
        {
            this.IP = ip;
            this.Port = port;
        }
    }
}
